#include "test_byte.h"
#include "string.h"
#include "stdlib.h"
#include "esp_system.h"
#include "lua_user_model.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

static int lua_print_task_info(lua_State *L){
    UBaseType_t num=uxTaskGetNumberOfTasks();
    TaskStatus_t *task=(TaskStatus_t*)malloc(sizeof(TaskStatus_t)*num);
    // 这里请打开配置中的 config USE_TRACE_FACILITY
    UBaseType_t temp=uxTaskGetSystemState(task,num,NULL);
    printf("----------------------------\r\n");
    printf("  %-5s %-20s\r\n","id","name");
    printf("----------------------------\r\n");
    
    if(temp>0){
        TaskStatus_t*p=NULL;
        for(char i=0;i<temp;i++){
            p=task+i;
            printf("  %-5d %-20s\r\n",p->xTaskNumber,p->pcTaskName);
        }
    }
    free(task);
    return 0;
}

static int lua_task_info(lua_State *L){
    UBaseType_t num=uxTaskGetNumberOfTasks();
    TaskStatus_t *task=(TaskStatus_t*)malloc(sizeof(TaskStatus_t)*num);
    // 这里请打开配置中的 config USE_TRACE_FACILITY
    UBaseType_t temp=uxTaskGetSystemState(task,num,NULL);
    //返回一个表
    lua_newtable(L);
    if(temp>0){
        TaskStatus_t*p=NULL;
        for(char i=0;i<temp;i++){
            p=task+i;
            char buff[40];
            sprintf(buff,"  %-5d %-20s",p->xTaskNumber,p->pcTaskName);
            //返回一个数组
            lua_pushnumber(L,i+1);
            lua_pushstring(L,buff);
            lua_rawset(L,-3);
            //下面返回一个table
            //lua_pushstring(L,"name");
            //lua_pushstring(L,buff);
            //lua_settable(L, -3);
        }
    }
    free(task);
    return 1;
}

//传入任务id，然后删除任务
static int lua_task_kill(lua_State *L){
    int id=luaL_checkinteger(L,1);
    UBaseType_t num=uxTaskGetNumberOfTasks();
    TaskStatus_t *task=(TaskStatus_t*)malloc(sizeof(TaskStatus_t)*num);
    // 这里请打开配置中的 config USE_TRACE_FACILITY
    UBaseType_t temp=uxTaskGetSystemState(task,num,NULL);
    if(temp>0){
        TaskStatus_t*p=NULL;
        for(char i=0;i<temp;i++){
            p=task+i;
            if(id==p->xTaskNumber){
                vTaskSuspend(p->xHandle);
                vTaskDelete(p->xHandle);
                break;
            }
        }
    }
    free(task);
    return 0;
}
static void test_task(void *pvParameters){
    char*str=NULL;
    //int size = (int)pvParameters;
    printf("point %p\r\n",str);
    //str=(char*)malloc(size);
    while(1){
        //printf("hello %p %d\r\n",str,size);
        vTaskDelay(25000/portTICK_PERIOD_MS);
    }
}

static int lua_task_test(lua_State *L){
    const char* name=luaL_checkstring(L,1);
    int size=luaL_checkinteger(L,2);
    TaskHandle_t handler;
    xTaskCreate(test_task, name, 4096, (void*)size, 5, &handler);
    return 0;
}

//测试延时
static int lua_task_delay(lua_State *L){
    int time=luaL_checkinteger(L,1);
    vTaskDelay(time/portTICK_PERIOD_MS);
    return 0;
}

//根据名字获取id
static int lua_get_task_id(lua_State *L){
    const char* name=luaL_checkstring(L,1);
    UBaseType_t num=uxTaskGetNumberOfTasks();
    TaskStatus_t *task=(TaskStatus_t*)malloc(sizeof(TaskStatus_t)*num);
    // 这里请打开配置中的 config USE_TRACE_FACILITY
    UBaseType_t temp=uxTaskGetSystemState(task,num,NULL);
    int pid=-1;
    if(temp>0){
        TaskStatus_t*p=NULL;
        for(char i=0;i<temp;i++){
            p=task+i;
            if(strcmp(name,p->pcTaskName)==0){
                pid=p->xTaskNumber;
                break;
            }
        }
    }
    free(task);
    lua_pushinteger(L,pid);

    return 1;
}

//测试在其他对象中生产自定义对象
static int lua_get_test_byte(lua_State *L){
    user_byte*bb=(user_byte*)malloc(20);
    user_byte**temp = (user_byte**)lua_newuserdata(L, sizeof(user_byte*));
    *temp=bb;
    //Lua->stack，得到全局元表位置-1,userdata位置-2
    luaL_getmetatable(L, "byte");
    //将元表赋值给位置-2的userdata，并弹出-1的元表
    lua_setmetatable(L, -2);
    return 1;
}
//获取自定义对象的真实数据
static int lua_get_test_byte_param(lua_State *L){
    int a1=luaL_checkinteger(L,1);
    int a2=luaL_checkinteger(L,3);
    int a3=luaL_checkinteger(L,4);
    printf("KK:%d ,%d ,%d\r\n",a1,a2,a3);
    //luaL_getmetatable(L, "byte");
    user_byte**temp=(user_byte**)lua_touserdata(L,2);
    if(temp!=NULL&&*temp!=NULL){
        printf("OK %s\r\n",(*temp)->buff);
    }else{
        printf("error\r\n");
    }
    return 0;
}

static const luaL_Reg sysfunc[] ={
    {"taskInfo", lua_task_info},
    {"printTaskInfo", lua_print_task_info},
    {"taskKill", lua_task_kill},
    {"getTaskId", lua_get_task_id},

    {"taskTest", lua_task_test},
    {"delay", lua_task_delay},
    {"sleep", lua_task_delay},
    {"testByte",lua_get_test_byte},
     {"testByteParam",lua_get_test_byte_param},


	{NULL, NULL}
};

//下面两个直接注册成模块
LUAMOD_API int luaopen_syslibs(lua_State *L) {
  luaL_newlib(L, sysfunc);
  return 1;
}
